package model

import (
	"common/helper"
	"database/sql"
	"errors"
	"fmt"
	g "github.com/doug-martin/goqu/v9"
	"github.com/valyala/fasthttp"
	"strconv"
)

type LotteryParam struct {
	Uid        int    `json:"uid"`
	OperatorId string `json:"operator_id"` // 渠道id
	BusinessId string `json:"business_id"` // 业务员id
	StartTime  string `json:"start_time"`  // 查询开始时间
	EndTime    string `json:"end_time"`    // 查询结束时间
	Page       int    `json:"page"`
	PageSize   int    `json:"page_size"`
	OderBY     string `json:"order_by"`
	OderType   string `json:"order_type"`
	UserId     string `json:"user_id"`

	Status  string `json:"status"`
	IssueId string `json:"issue_id"`
	PrizeId string `json:"prize_id"`

	Rankname string  `json:"rankname"`
	Rate     float64 `json:"rate"`
	Count    int     `json:"count"`

	SerialNo string `json:"serial_no"`
}

type LotteryConfigBase struct {
	Id                 int     `db:"id" json:"id"`
	IsEnabled          int     `db:"is_enabled" json:"is_enabled"`
	OpenHour           int     `db:"open_hour" json:"open_hour"`
	DeductionRate      float64 `db:"deduction_rate" json:"deduction_rate"`
	MinRechargeAmount  int     `db:"min_recharge_amount" json:"min_recharge_amount"`
	GreedyRate         int     `db:"greedy_rate" json:"greedy_rate"`
	Mode               int     `db:"mode" json:"mode"`
	BaseAward          int     `db:"base_award" json:"base_award"`
	H5RefreshIntervalS int     `db:"h5_refresh_interval_s" json:"h5_refresh_interval_s"`
	DiscountRate       int     `db:"discount_rate" json:"discount_rate"`
	RuleText           string  `db:"rule_text" json:"rule_text"`
	//PoolManualAmount int    `db:"pool_manual_amount" json:"pool_manual_amount"`
	CreatedAt string `db:"created_at" json:"created_at"`
	UpdatedAt string `db:"updated_at" json:"updated_at"`
}

type LotteryConfigBaseRetData struct {
	T int                 `cbor:"t" json:"total"`
	D []LotteryConfigBase `cbor:"d" json:"d"`
}

func GetLotteryConfigBase(param LotteryParam, ctx *fasthttp.RequestCtx) (LotteryConfigBaseRetData, error) {
	data := LotteryConfigBaseRetData{}
	table := "lottery_config"
	where := "1=1"
	join := ""
	oderBy := "a.id"
	oderType := "desc"

	if param.StartTime != "" {
		where += " and a.created_at>='" + param.StartTime + "'"
	}
	if param.EndTime != "" {
		where += " and a.created_at<='" + param.EndTime + "'"
	}
	order := oderBy + " " + oderType
	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from " + table + " as a where " + where
		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}
		if data.T == 0 {
			return data, nil
		}
	}

	field := "a.*"
	query := "select " + field + " from " + table + "  as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	return data, nil
}

func UpdateLotteryConfigBase(param LotteryConfigBase, isDelete int8) error {
	table := "lottery_config"
	query := ""
	record := param
	if param.Id > 0 {
		if isDelete == 0 {
			query, _, _ = dialect.Update(table).Set(record).Where(g.Ex{"id": param.Id}).ToSQL()
		} else {
			query, _, _ = dialect.Delete(table).Where(g.Ex{"id": param.Id}).ToSQL()
		}
	} else {
		query, _, _ = dialect.Insert(table).Rows(record).ToSQL()
	}
	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return errors.New("数据库错误")
	}
	return nil
}

type LotteryIssueBase struct {
	IssueId           int    `db:"issue_id" json:"issue_id"`
	StartTime         string `db:"start_time" json:"start_time"`
	EndTime           string `db:"end_time" json:"end_time"`
	PoolAmount        int    `db:"pool_amount" json:"pool_amount"`
	TotalParticipants int    `db:"total_participants" json:"total_participants"`
	TotalShares       int    `db:"total_shares" json:"total_shares"`
	Status            string `db:"status" json:"status"`
	SnapshotConfig    string `db:"snapshot_config" json:"snapshot_config"`
	RealUserDeposit   int    `db:"real_user_deposit" json:"real_user_deposit"`
	VrtualUserDeposit int    `db:"virtual_user_deposit" json:"virtual_user_deposit"`
	CreatedAt         string `db:"created_at" json:"created_at"`
	UpdatedAt         string `db:"updated_at" json:"updated_at"`

	BaseAward        int `db:"base_award" json:"base_award"`
	TaxAward         int `db:"tax_award" json:"tax_award"`
	TaxRealAward     int `db:"tax_real_award" json:"tax_real_award"`
	RealParticipants int `db:"real_participants" json:"real_participants"`
	RealShares       int `db:"real_shares" json:"real_shares"`
}

type LotteryIssueBaseRetData struct {
	T int                `cbor:"t" json:"total"`
	D []LotteryIssueBase `cbor:"d" json:"d"`
}

func GetLotteryIssueBase(param LotteryParam, ctx *fasthttp.RequestCtx) (LotteryIssueBaseRetData, error) {
	data := LotteryIssueBaseRetData{}
	table := "lottery_issue"
	where := "1=1"
	join := ""
	oderBy := "a.issue_id"
	oderType := "desc"

	if param.StartTime != "" {
		where += " and a.start_time>='" + param.StartTime + "'"
	}
	if param.EndTime != "" {
		where += " and a.end_time<='" + param.EndTime + "'"
	}
	if param.Status != "" {
		where += " and a.status='" + param.Status + "'"
	}
	if param.IssueId != "" {
		where += " and a.issue_id='" + param.IssueId + "'"
	}

	order := oderBy + " " + oderType
	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from " + table + " as a where " + where
		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}
		if data.T == 0 {
			return data, nil
		}
	}

	field := "a.*"
	query := "select " + field + " from " + table + "  as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	return data, nil
}

func UpdateLotteryIssueBase(param LotteryIssueBase, isDelete int8) error {
	table := "lottery_issue"
	query := ""
	record := param

	has := LotteryIssueBase{}
	meta.MerchantDB.Get(&has, fmt.Sprintf("select * from "+table+" where issue_id='%d'", param.IssueId))

	if has.IssueId > 0 {
		if isDelete == 0 {
			query, _, _ = dialect.Update(table).Set(record).Where(g.Ex{"issue_id": param.IssueId}).ToSQL()
		} else {
			query, _, _ = dialect.Delete(table).Where(g.Ex{"issue_id": param.IssueId}).ToSQL()
		}
	} else {
		query, _, _ = dialect.Insert(table).Rows(record).ToSQL()
	}
	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return errors.New("数据库错误")
	}
	return nil
}

type LotteryParticipantBase struct {
	Id             int    `db:"id" json:"id"`
	IssueId        int    `db:"issue_id" json:"issue_id"`
	UserId         string `db:"user_id" json:"user_id"`
	RechargeAmount int    `db:"recharge_amount" json:"recharge_amount"`
	Shares         int    `db:"shares" json:"shares"`
	IsEligible     int    `db:"is_eligible" json:"is_eligible"`
	CreatedAt      string `db:"created_at" json:"created_at"`
	UpdatedAt      string `db:"updated_at" json:"updated_at"`
}

type LotteryParticipantBaseRetData struct {
	T int                      `cbor:"t" json:"total"`
	D []LotteryParticipantBase `cbor:"d" json:"d"`
}

func GetLotteryParticipantRecord(param LotteryParam, ctx *fasthttp.RequestCtx) (LotteryParticipantBaseRetData, error) {
	data := LotteryParticipantBaseRetData{}
	table := "lottery_participant"
	where := "1=1"
	join := ""
	oderBy := "a.id"
	oderType := "desc"

	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		where += " and b.operator_id=" + loginUser.Operator
	}
	if loginUser.Businsess != "" {
		where += " and b.business_id=" + loginUser.Businsess
	}

	if param.StartTime != "" {
		where += " and a.created_at>='" + param.StartTime + "'"
	}
	if param.EndTime != "" {
		where += " and a.created_at<='" + param.EndTime + "'"
	}
	if param.UserId != "" {
		where += " and a.user_id='" + param.UserId + "'"
	}
	if param.IssueId != "" {
		where += " and a.issue_id='" + param.IssueId + "'"
	}
	join += " left join tbl_member_base as b on b.uid=a.user_id" //玩家表

	order := oderBy + " " + oderType
	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from " + table + " as a where " + where
		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}
		if data.T == 0 {
			return data, nil
		}
	}

	field := "a.*"
	query := "select " + field + " from " + table + "  as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	return data, nil
}

type LotteryPrizeBase struct {
	Id             int     `db:"id" json:"id"`
	IssueId        int     `db:"issue_id" json:"issue_id"`
	PrizeLevel     int     `db:"prize_level" json:"prize_level"`
	PrizeName      string  `db:"prize_name" json:"prize_name"`
	AllocationRate float64 `db:"allocation_rate" json:"allocation_rate"`
	WinnerQuota    int     `db:"winner_quota" json:"winner_quota"`
	PresetWinners  string  `db:"preset_winners" json:"preset_winners"`
	CreatedAt      string  `db:"created_at" json:"created_at"`
	UpdatedAt      string  `db:"updated_at" json:"updated_at"`
}

type LotteryPrizeBaseRetData struct {
	T int                `cbor:"t" json:"total"`
	D []LotteryPrizeBase `cbor:"d" json:"d"`
}

func GetLotteryPrizeBase(param LotteryParam, ctx *fasthttp.RequestCtx) (LotteryPrizeBaseRetData, error) {
	data := LotteryPrizeBaseRetData{}
	table := "lottery_prize"
	where := "1=1"
	join := ""
	oderBy := "a.id"
	oderType := "desc"

	if param.StartTime != "" {
		where += " and a.created_at>='" + param.StartTime + "'"
	}
	if param.EndTime != "" {
		where += " and a.created_at<='" + param.EndTime + "'"
	}

	if param.IssueId != "" {
		where += " and a.issue_id='" + param.IssueId + "'"
	}

	order := oderBy + " " + oderType
	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from " + table + " as a where " + where
		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}
		if data.T == 0 {
			return data, nil
		}
	}

	field := "a.*"
	query := "select " + field + " from " + table + "  as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	return data, nil
}

func UpdateLotteryPrizeBase(param LotteryPrizeBase, isDelete int8) error {
	table := "lottery_prize"
	query := ""
	record := param
	if param.Id > 0 {
		if isDelete == 0 {
			query, _, _ = dialect.Update(table).Set(record).Where(g.Ex{"id": param.Id}).ToSQL()
		} else {
			query, _, _ = dialect.Delete(table).Where(g.Ex{"id": param.Id}).ToSQL()
		}
	} else {
		query, _, _ = dialect.Insert(table).Rows(record).ToSQL()
	}
	//fmt.Println(query)
	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return errors.New("数据库错误")
	}
	return nil
}

type LotteryWinnerBase struct {
	Id        int     `db:"id" json:"id"`
	SerialNo  string  `db:"serial_no" json:"serial_no"`
	Uid       int     `db:"uid" json:"uid"`
	Username  string  `db:"username" json:"username"`
	Level     int     `db:"level" json:"level"`
	Award     float64 `db:"award" json:"award"`
	CreatedAt string  `db:"created_at" json:"created_at"`
	LevelDesp string  `db:"level_desp" json:"level_desp"`
	IsReal    int     `db:"is_real" json:"is_real"`
}

type LotteryWinnerBaseRetData struct {
	T int                 `cbor:"t" json:"total"`
	D []LotteryWinnerBase `cbor:"d" json:"d"`
}

func GetLotteryWinnerRecord(param LotteryParam, ctx *fasthttp.RequestCtx) (LotteryWinnerBaseRetData, error) {
	data := LotteryWinnerBaseRetData{}
	table := "tbl_rec_lottery"
	where := "1=1"
	join := ""
	oderBy := "a.id"
	oderType := "desc"

	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		where += " and b.operator_id=" + loginUser.Operator
	}
	if loginUser.Businsess != "" {
		where += " and b.business_id=" + loginUser.Businsess
	}

	//if param.StartTime != "" {
	//	where += " and a.created_at>='" + param.StartTime + "'"
	//}
	//if param.EndTime != "" {
	//	where += " and a.created_at<='" + param.EndTime + "'"
	//}
	if param.StartTime != "" {
		StartTime, _ := helper.TimeToLoc(param.StartTime, loc)
		where += " and a.created_at>='" + strconv.FormatInt(StartTime, 10) + "'"
	}
	if param.EndTime != "" {
		EndTime, _ := helper.TimeToLoc(param.EndTime, loc)
		where += " and a.created_at<='" + strconv.FormatInt(EndTime, 10) + "'"
	}
	if param.UserId != "" {
		where += " and a.uid='" + param.UserId + "'"
	}
	if param.Uid != 0 {
		where += " and a.uid=" + strconv.Itoa(param.Uid)
	}
	if param.SerialNo != "" {
		where += " and a.serial_no='" + param.SerialNo + "'"
	}
	if param.PrizeId != "" {
		where += " and a.prize_id='" + param.PrizeId + "'"
	}
	join += " left join tbl_member_base as b on b.uid=a.uid" //玩家表

	order := oderBy + " " + oderType
	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from " + table + " as a where " + where
		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}
		if data.T == 0 {
			return data, nil
		}
	}

	field := "a.*"
	query := "select " + field + " from " + table + "  as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	return data, nil
}

type LotteryPrizeRule struct {
	Id       int     `db:"id" json:"id"`
	Rankname string  `db:"rankname" json:"rankname"`
	Rate     float64 `db:"rate" json:"rate"`
	Count    int     `db:"count" json:"count"`
}

type LotteryPrizeRuleRetData struct {
	T int                `cbor:"t" json:"total"`
	D []LotteryPrizeRule `cbor:"d" json:"d"`
}

func GetLotteryPrizeRule(param LotteryParam, ctx *fasthttp.RequestCtx) (LotteryPrizeRuleRetData, error) {
	data := LotteryPrizeRuleRetData{}
	table := "tbl_cfg_lottery_prize_rule"
	where := "1=1"
	join := ""
	oderBy := "a.count"
	oderType := "asc"

	if param.StartTime != "" {
		where += " and a.created_at>='" + param.StartTime + "'"
	}
	if param.EndTime != "" {
		where += " and a.created_at<='" + param.EndTime + "'"
	}

	if param.IssueId != "" {
		where += " and a.issue_id='" + param.IssueId + "'"
	}

	order := oderBy + " " + oderType
	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from " + table + " as a where " + where
		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}
		if data.T == 0 {
			return data, nil
		}
	}

	field := "a.*"
	query := "select " + field + " from " + table + "  as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	return data, nil
}

func UpdateLotteryPrizeRule(param LotteryPrizeRule, isDelete int8) error {
	table := "tbl_cfg_lottery_prize_rule"
	query := ""
	record := param
	if param.Id > 0 {
		if isDelete == 0 {
			query, _, _ = dialect.Update(table).Set(record).Where(g.Ex{"id": param.Id}).ToSQL()
		} else {
			query, _, _ = dialect.Delete(table).Where(g.Ex{"id": param.Id}).ToSQL()
		}
	} else {
		query, _, _ = dialect.Insert(table).Rows(record).ToSQL()
	}
	//fmt.Println(query)
	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return errors.New("数据库错误")
	}
	return nil
}
